%==========================================================================
%=  This file is part of the Sound Restoration Project
%=  (c) Copyright Industrial Mathematics Institute
%=                University of South Carolina, Department of Mathematics
%=  ALL RIGHTS RESERVED
%=
%=  Author: Borislav Karaivanov
%==========================================================================

%==========================================================================
% List of the files on which this procedure depends:
%
% setLogWritingFunctHandle.m
% writeToLogFile.m
%
%==========================================================================

%==========================================================================
% The function "saveSound" saves a given sound signal to an ascii file and
% as an audio .wav file.
% INPUT: "soundArr" is a column vector holding the complete sound signal.
% "fileNamePrefix" is a string specifying the common prefix (including full
% directory path) in the name of the file where the complete sound signal
% is to be stored.
% "samplingRate" specifies the sampling rate of the provided sound signal.
% "maxAmplitude" specifies the desired maximal amplitude that the modified
% signal stored in the audio .wav file should have.
% "bitsPerSample" is an optional parameter specifying the number of bits to
% be used for encoding a single sample.
% "reSamplingRate" is an optional parameter specifying a new sampling rate
% at which the given sound signal is to be resampled before being saved to
% an audio .wav file. By default, the original sampling rate is preserved.
% "writeToLogFunctHandle" is an optional function handle which writes to a
% fixed log text file if keeping a log is requested, or does nothing
% otherwise.
% OUTPUT: "wavFileName" returns the name of the audio .wav file.
%==========================================================================
function wavFileName = saveSound(soundArr, fileNamePrefix, samplingRate, ...
    maxAmplitude, bitsPerSample, reSamplingRate, writeToLogFunctHandle)

% Use the existing global variables to determine whether visualization is
% required, and what common prefix and file extension are to be used for
% the names of the image files saving snapshots of figures.
global globalDoVisualize globalShotFileNamePrefix globalShotFileExt
if (globalDoVisualize ~= true)
    doVisualize = false;
else
    doVisualize = true;
    shotFileNamePrefix = globalShotFileNamePrefix;
    shotFileExt = globalShotFileExt;
end

if (nargin < 4)
    maxAmplitude = 0.4;
end
if (nargin < 5)
    bitsPerSample = 16;
end
if (nargin < 6)
    reSamplingRate = samplingRate;
end
if (nargin < 7)
    writeToLogFunctHandle = @(x) '';
end


% Resample the sound signal at the desired sampling rate.
if (reSamplingRate ~= samplingRate)
    [p, q] = rat(reSamplingRate/samplingRate, 0.0001);
    soundArr = resample(soundArr, p, q);
    samplingRate = reSamplingRate;
end

% Plot the sound signal versus time, if desired.
if (doVisualize == true)
    figHandle = figure;
    t = linspace(0, numel(soundArr)/samplingRate, numel(soundArr));
    plot(t, soundArr)
    xlabel('time (sec)');
    ylabel('relative signal strength');
    % Maximize the figure to cover the whole screen.
    set(figHandle, 'Position', get(0, 'ScreenSize'));
    % Save a snapshot.
    shotFileName = [shotFileNamePrefix 'AudioWave.' shotFileExt];
    print(gcf, ['-d' shotFileExt], shotFileName);
    % Close the figure.
    close(figHandle);
    
    % Save the sound signal in an ascii file.
    soundFileName = [shotFileNamePrefix 'AudioWave.txt'];
    soundFileId = fopen(soundFileName, 'w');
    if (soundFileId == -1)
        writeToLogFunctHandle(['Warning in saveSound: Unable to open the file ' soundFileName ' for writing.']);
    end
    fprintf(soundFileId, '%.10f \n', soundArr);
    fclose(soundFileId);
end

% Construct a name for the .wav file where the sound signal is to be saved.
wavFileName = [fileNamePrefix '_Amp' num2str(maxAmplitude) ...
    '_BpS' num2str(bitsPerSample) '_SpS' num2str(samplingRate) '.wav'];
% Normalize the sound array entries to fit in [-maxAmplitude, maxAmplitude].
minSound = min(soundArr);
maxSound = max(soundArr);
if (maxSound == minSound)
    writeToLogFunctHandle('Warning in saveSound: Constant signal.');
    return;
end
% Save the sound signal in a .wav file.
wavwrite(maxAmplitude*(2*soundArr - (maxSound + minSound))/(maxSound - minSound), ...
    samplingRate, bitsPerSample, wavFileName);


% Write info to a log file.
writeToLogFunctHandle(['max sound amplitude: ' num2str(maxAmplitude)]);
writeToLogFunctHandle(['bits per sound sample: ' num2str(bitsPerSample)]);
writeToLogFunctHandle(['sampling rate: ' num2str(samplingRate)]);
writeToLogFunctHandle(['sound file name: ' wavFileName]);

return;
% end of the function "saveSound"
